<?php
$pathToThis = pathinfo(__FILE__);
$ret = getcwd();
chdir($pathToThis['dirname']);

require_once("../excecoes/SearchException.class.php");
require_once("../report/SearchTable.class.php");
require_once("../componentes/InputText.class.php");
require_once("../componentes/InputSubmit.class.php");
require_once("../bd/Persistencia.class.php");
require_once("../base/Constantes.class.php");

class Search
{
	private $result = null;
	private $info = null;
	private $control = array();
	private $total = 0;
	private $nome = "procura";
	// 0 -> mixed; 1 -> string; 2 -> int; 3 -> array;
	private $knownParameters = Array(
		'ChaveDeRetorno'=>0,
		'Campos'=>3,
		'Ordem'=>1,
		'Paginacao'=>2,
		'Tabelas'=>1,
		'Condicao'=>1,
		'Selecionar'=>1,
		'Renderizar'=>1,
		'CampoRetorno'=>1,
		'FormularioRetorno'=>1,
		'ClasseFormulario'=>1
	);

	function __construct($nome = null, $xml = null)
	{
		@session_start(); // Garante que a sessao serah inicializada

		$this->getFromXML("xml/padrao.xml");
		$this->readFromSession();
		if($nome)
			$this->nome = $nome;
		if($xml)
		{
			$this->getFromXML(file_get_contents($xml));
		}
	}
	
	public function getReport()
	{
		$tbl = new SearchTable($this);
		if($_SERVER['REQUEST_METHOD']=="POST")
		{
			$this->flush();
			$tbl->resetStart();
		}
		if(!isset($this->info['Renderizar']))
		{
			$tbl->setRenderOption("RenderSequence", explode(",", $this->info['Selecionar']));
			$tbl->setRenderOption("RenderIgnore", array($this->info['ChaveDeRetorno']));
		}
		else
		{
			$tbl->setRenderOption("RenderSequence", explode(",", $this->info['Renderizar']));
		}
		$tbl->setRenderOption("RenderKeys", array($this->info['ChaveDeRetorno']));
		$tbl->setRenderOption("returnLinkA","javascript://");
		$tbl->setRenderOption("returnLinkOnClick","executaBusca('".$this->info['FormularioRetorno']."', '".$this->info['CampoRetorno']."', '".$this->info['ClasseFormulario']."', '".Constantes::TRATADOR_ACTION."procurar".Constantes::TRATADOR_CLASS_CALL.$this->info['ClasseFormulario']."', '[R_KEY0]');");
//		$tbl->setRenderOption("IncludeOnHeader",'<script language="javascript" type="text/javascript" src="lib/cbdu_admin.js"></script>');
		return $tbl->render();
	}

	public function flush()
	{
		$this->control = array();
		$this->writeToSession();
	}
	
	public function getForm()
	{
		if(!isset($this->info['Campos']) || count($this->info['Campos']) == 0)
			throw new SearchException("N&atilde;o h&aacute; campos cadastrados");
		$ret = '<FORM NAME="'.$this->nome.'" METHOD="POST" ACTION="?">';
		foreach($this->info['Campos'] as $campo)
		{
			if(!isset($campo['nome']))
				throw new SearchException("Erro ao renderizar campo: 'nome' n&atilde;o encontrado");
			if(!isset($campo['id']))
				throw new SearchException("Erro ao renderizar campo: 'id' n&atilde;o encontrado");
			if(!isset($campo['mlen']))
				$campo['mlen'] = 0;
			if(!isset($campo['class']))
				$campo['class'] = "InputText";
			$c = new InputText($campo['id'], false, null, $campo['mlen'], $campo['class']);
			$ret .= $campo['nome'].": ".$c->render($campo['id'], $this->nome)."<br />";
		}
		$s = new InputSubmit("Procurar");
		return $ret.$s->render("Enviar", $this->nome)."</FORM>";
	}
	
	public function getFromXML($data)
	{
		$parser = xml_parser_create();
		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
		xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
		xml_parse_into_struct($parser, $data, $values, $tags);
		xml_parser_free($parser);

		$buffer = false;
		$bff = array();
		foreach($values as $value)
		{
			if($value['tag'] != 'Procura')
			{
				if($value['tag'] == 'Campos' && $value['type'] == 'open')
				{
					$buffer = true;
				}
				else if($value['tag'] == 'Campos' && $value['type'] == 'close')
				{
					$buffer = false;
					$this->setParameter('Campos', $bff);
				}
				else
				{
					if($buffer)
					{
						$bff[] = $value['attributes'];
					}
					else
					{
						$this->setParameter($value['tag'], $value['attributes']['valor']);
					}
				}
			}
		}

	}
	
	public function setParameter($parameter, $value)
	{
		if(array_key_exists($parameter, $this->knownParameters))
		{
			switch($this->knownParameters[$parameter])
			{
				case 0: // mixed
					break;
				case 1: // string
					if(!is_string($value))
						throw new SearchException("Erro ao modificar o parametro '".$parameter."'. Esperado: String. Encontrado: ".gettype($value));
					break;
				case 2: // int
					if(!is_numeric($value))
						throw new SearchException("Erro ao modificar o parametro '".$parameter."'. Esperado: Inteiro. Encontrado: ".gettype($value));
					break;
				case 3: // array
					if(!is_array($value))
						throw new SearchException("Erro ao modificar o parametro '".$parameter."'. Esperado: Array. Encontrado: ".gettype($value));
					break;
				default:
					throw new SearchException("Tipo de dado desconhecido");
			}
			$this->info[$parameter] = $value;
		}
		else
			throw new SearchException("Parametro '".$parameter."' desconhecido.");
	}
	
	public function fetch($start = 0)
	{
		$p = Persistencia::getInstance();
		$conexao = $p->getConnection();
		$this->control['start'] = $start;
		$fetched = null;
		if(!isset($this->control['searchBy'])) // What Im searching for?
		{
			$this->control['searchBy'] = Array();
			foreach($this->info['Campos'] as $campo)
			{
				if(!isset($_POST[$campo['id']]))
					throw new SearchException("Campo indefinido em POST");
				if($_POST[$campo['id']] != "")
					$this->control['searchBy'][] = array($campo['idS'], $_POST[$campo['id']]);
			}
		}
		if(!isset($this->control['total'])) // Total results
		{
			$sql = "SELECT COUNT(*) AS total FROM ".$this->info['Tabelas'];
			if(isset($this->info['Condicao']))
				$sql .= " WHERE ".$this->info['Condicao'];
			$totalKeys = count($this->control['searchBy']);
			if($totalKeys > 0)
			{
				if(!isset($this->info['Condicao']))
					$sql .= " WHERE ";
				else
					$sql .= " AND ";
				for($i = 0; $i < $totalKeys; $i++)
				{
					if($i > 0) $sql .= " AND ";
					$sql .= $this->control['searchBy'][$i][0]." LIKE '%".$this->control['searchBy'][$i][1]."%'";
				}
			}

			$resultSet = mysql_query($sql, $conexao) or die(mysql_error());
			$result = mysql_fetch_array($resultSet, MYSQL_ASSOC);
			$this->control['total'] = $result['total'];
		}
		$sql = "SELECT ".$this->info['Selecionar']." FROM ".$this->info['Tabelas'];
			if(isset($this->info['Condicao']))
				$sql .= " WHERE ".$this->info['Condicao'];
		$fetched = array();
		$totalKeys = count($this->control['searchBy']);
		if($totalKeys > 0)
		{
			if(!isset($this->info['Condicao']))
				$sql .= " WHERE ";
			else
				$sql .= " AND ";
			for($i = 0; $i < $totalKeys; $i++)
			{
				if($i > 0) $sql .= " AND ";
				$sql .= $this->control['searchBy'][$i][0]." LIKE '%".$this->control['searchBy'][$i][1]."%'";
			}
		}
		$sql .= " ORDER BY ".$this->info['Ordem']." LIMIT ".$this->control['start'].", ".$this->info['Paginacao'];
		$resultSet = mysql_query($sql, $conexao) or die(mysql_error());
		while(($result = mysql_fetch_array($resultSet, MYSQL_ASSOC)) !== false)
			$fetched[] = $result;

		$this->writeToSession();
		return $fetched;
	}
	
	public function getControlTotal()
	{
		return $this->control['total'];
	}
	public function getControlPage()
	{
		return $this->info['Paginacao'];
	}
	
	private function writeToSession()
	{
		$_SESSION[$this->nome."_control"] = serialize($this->control);
	}
	
	private function readFromSession()
	{
		if(isset($_SESSION[$this->nome."_control"]))
			$this->control = unserialize($_SESSION[$this->nome."_control"]);
	}
}

chdir($ret);
?>